package gspushmq.v1.subscribe.send;

import java.util.Date;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.java_websocket.WebSocket;

import com.google.common.collect.Sets;

import gspushmq.model.ConsumerWays;
import gspushmq.model.DataMessage;
import gspushmq.model.Message;
import gspushmq.model.MessageType;
import gspushmq.model.User;
import gspushmq.model.VersionEnum;
import gspushmq.util.DateUtil;
import gspushmq.util.GGLogger;
import gspushmq.util.SysUtil;
import gspushmq.v1.produce.GGDataStorage;
import gspushmq.v1.subscribe.GGSubscribe;
import gspushmq.v1.subscribe.send.core.GGSend;

/**
 * 推送数据给前端
 *
 * @author yutao
 * @version 1.0
 * @company 上海朝阳永续信息技术有限公司
 * @copyright (c) 2016 SunTime Co'Ltd Inc.All rights reserved.
 * @date 2018年11月15日下午4:51:17
 * @since JDK1.7
 */
public class GGSendSys extends GGSend {

    /**
     * 推送系统消息
     *
     * @author yutao
     * @date 2018年11月15日下午5:29:41
     */
    private void handlerSys() {

        while (true) {
            try {
                DataMessage dataMessage = GGDataStorage.dataMessageBlockingQueue.take();
                MessageType messType = new MessageType(dataMessage);
                if (StringUtils.isBlank(messType.getMq_sub_type()) && StringUtils.isBlank(messType.getMq_type())) {
                    continue;
                }
                //消息失效
                if (DateUtil.compare(new Date(), dataMessage.getExpireDate()) > 0) {
                    continue;
                }
                //消息订阅用户
                Set<Message> messageSet = GGSubscribe.messWocketMap.get(messType);
                if (messageSet == null || messageSet.size() == 0) {
                    //没有在线订阅用户
                    continue;
                }
                StringBuffer buffer = new StringBuffer();
                for (Message message : messageSet){
                    if (message.getProduct_line().equals(dataMessage.getProductLine().toString())) {
                        buffer.append("uid=").append(message.getAccount_id())
                                .append("productLine=").append(message.getProduct_line())
                                .append("pro=").append(message.getPro_type())
                                .append("ws=").append(message.getWst()==null ? null :message.getWst().isOpen())
                                .append("\n");
                    }
                }
                GGLogger.info(getClass(),
                        new StringBuffer("---------->在线消费----------> ").append("\n")
                        .append("消息类型：").append(dataMessage.getMqSubType()).append("\n")
                                .append("消费方式：").append(dataMessage.getCrowdType()).append("\n")
                                .append("消费对象：").append(dataMessage.getCrowdValue()).append("\n")
                        .append("消费用户：").append(buffer.toString())

                );
                //本次需要推送用户
                Iterator<Message> messIt = messageSet.iterator();
                while (messIt.hasNext()) {
                    Message mess = messIt.next();
                    WebSocket wst = mess.getWst();
                    User user = GGSubscribe.wstUser.get(wst);
                    if (user == null){
                        continue;
                    }
                    //注入用户名
                    mess.setAccount_name(user.getAccountName());
                    //消息推送方式
                    String target = dataMessage.getCrowdType();
                    String targetValue = dataMessage.getCrowdValue();
                    Integer bproductLine = dataMessage.getProductLine();
                    String fproductLine = mess.getProduct_line();
                    String pro = mess.getPro_type();
                    String accountId = mess.getAccount_id();
                    //权限丢失
                    if (StringUtils.isBlank(pro)
                            //账号丢失
                            || StringUtils.isBlank(accountId)
                            || user == null
                            //用户名丢失
                            || StringUtils.isBlank(user.getAccountName())
                            //推送方式丢失
                            || StringUtils.isBlank(target)
                            //推送对象丢失
                            || StringUtils.isBlank(targetValue)) {
                        //暂不推送
                        continue;
                    }
                    if (bproductLine != null && !bproductLine.toString().equals(fproductLine)) {
                        //若后台生产带有产品线的消息，则前端消费必须满足产品线相同！
                        continue;
                    }
                    //获取推送对象列表
                    Set<String> targetValues = Sets.newHashSet(StringUtils.split(targetValue, ";"));
                    //前端消费凭证字符串
                    String ftargetValue = null;

                    //Tag推送（版本推送）
                    if (ConsumerWays.TAG.getWay().equals(target)) {
                        ftargetValue = String.valueOf(VersionEnum.getNumber(Integer.valueOf(fproductLine), Integer.valueOf(pro)));
                    } else if (ConsumerWays.ACCOUNT.getWay().equals(target)) {
                        //account推送
                        //用户名
                        ftargetValue = user.getAccountName();
                    } else if (ConsumerWays.ALIAS.getWay().equals(target)) {
                        //id推送
                        ftargetValue = accountId;
                    }
                    // 推送，忽略账户大小写
                    if (StringUtils.isNotBlank(ftargetValue)) {
                        Boolean isValidate = false;
                        for (String btv : targetValues) {
                            if (ftargetValue.equalsIgnoreCase(btv)) {
                                isValidate = true;
                                break;
                            }
                        }
                        if (isValidate) {
                            if (wst.isOpen()) {
                                //在线消费
                                SysUtil.sendWebSocket(mess,wst,dataMessage);
                            } else {
                                messIt.remove();
                            }
                        }
                    }
                }

            } catch (Exception e) {
                GGLogger.error(getClass(), "--消费异常：" + e);
            }
        }

    }

    @Override
    public void handler() {
        handlerSys();
    }


}
